package com.example.web;

/**
 * Created by hldev on 17-2-15.
 */

import com.example.business.FileSourceService;
import com.example.data.DataUtils;
import com.example.data.model.FileSource;
import com.example.exception.ValidateException;
import com.example.page.Page;
import com.example.page.Pageable;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 上传下载 API
 */
@RestController
@RequestMapping("/demo/file")
@Api(value = "demo-file", description = "上传下载")
public class FileSourceController {

    private final FileSourceService fileSourceService;

    @Autowired
    public FileSourceController(FileSourceService fileSourceService) {
        this.fileSourceService = fileSourceService;
    }

    @PostMapping
    public void upload(HttpServletRequest request,
                         HttpServletResponse response) throws Exception {

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd/HH");
        /** 构建文件保存的目录* */
        String logoPathDir = "/file/upload/"
                + dateformat.format(new Date());
        /** 得到文件保存目录的真实路径* */
        String logoRealPathDir = request.getSession().getServletContext()
                .getRealPath(logoPathDir);
        /** 根据真实路径创建目录* */
        File logoSaveFile = new File(logoRealPathDir);
        if (!logoSaveFile.exists())
            logoSaveFile.mkdirs();
        /** 页面控件的文件流* */
        MultipartFile multipartFile = multipartRequest.getFile("file");
        /** 获取文件的后缀* */
        String suffix = multipartFile.getOriginalFilename().substring(
                multipartFile.getOriginalFilename().lastIndexOf("."));
        /** 使用UUID生成文件名称* */
        String logImageName = UUID.randomUUID().toString() + suffix;// 构建文件名称
        /** 拼成完整的文件保存路径加文件* */
        String fileName = logoRealPathDir + File.separator + logImageName;
        FileSource fs = new FileSource();
        fs.setFilePath(fileName);
        fs.setFileName(multipartFile.getOriginalFilename());
        fs.setDescription(multipartRequest.getParameter("description"));
        fs.setCreateBy(Integer.parseInt(multipartRequest.getParameter("createBy")));
        fs.setCreateName(multipartRequest.getParameter("createName"));
        fs.setCreateDate(LocalDateTime.now());
        fileSourceService.createFile(fs);
        File file = new File(fileName);
        try {
            multipartFile.transferTo(file);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /** 打印出上传到服务器的文件的绝对路径* */
        System.out.println("****************" + fileName + "**************");
    }

    @GetMapping(path = "download")
    public void download(@RequestParam String path, HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @PutMapping
    @ApiOperation(value = "更新文章", notes = "更新文章")
    public FileSource updateFile(@RequestBody @Valid FileSource fileSource, BindingResult result) {
        if (result.hasErrors()) {
            throw new ValidateException(result);
        }
//        Long x = AuthToken.getFromThreadLocal().get().ownerId;
//        file.setUpdateBy(x);
//        file.setUpdateDate(LocalDateTime.now());
        fileSourceService.updateFile(fileSource);
        return fileSource;
    }

    @DeleteMapping(path = "{id}")
    @ApiOperation(value = "根据id删除文章", notes = "根据id删除文章")
    public ResponseEntity deleteFile(@PathVariable Integer id) {
        fileSourceService.deleteFile(id);
        return new ResponseEntity(HttpStatus.OK);
    }

    @GetMapping(path = "{id}")
    @ApiOperation(value = "根据id查找文章", notes = "根据id查找文章")
    public ResponseEntity<FileSource> findOne(@PathVariable Long id) {
        return fileSourceService.findById(id)
                .map(FileSource -> new ResponseEntity<>(FileSource, HttpStatus.OK))
                .orElseGet(() -> new ResponseEntity<FileSource>(HttpStatus.NOT_FOUND));
    }

    @GetMapping(path = "list")
    @ApiOperation(value = "查找所有文章", notes = "查找所有文章")
    public List<FileSource> findAll() {
        return fileSourceService.findAll();
    }

    @GetMapping(path = "page")
    @ApiOperation(value = "查找所有文章并分页", notes = "查找所有文章并分页")
    public Page<FileSource> findPage(
            @RequestParam(name = "fileName", required = false) String fileName,
            @RequestParam(name = "createName", required = false) String createName,
            @RequestParam(name = "status", required = false) Integer status,
            @RequestParam(name = "beginDate", required = false) String beginDate,
            @RequestParam(name = "endDate", required = false) String endDate,
            @RequestParam(value = "page", required = false, defaultValue = Pageable.STR_PAGE_INDEX) Integer page,
            @RequestParam(value = "size", required = false, defaultValue = "5") Integer size,
            @RequestParam(value = "orderField", required = false, defaultValue = "CREATE_DATE") String orderField,
            @RequestParam(value = "direction", required = false, defaultValue = "DESC") String direction) {
        Pageable pageable = DataUtils.pageable(page, size, orderField, direction);
        return fileSourceService.findPage(pageable, fileName, createName, status, beginDate, endDate);
    }
}